feat(research): the equities DCA benchmark, read per ticker (#371) - #699
Merged
Conversation
Alpaca Phase C's second half, and the last of #371. It follows the cost-fidelity document in that order deliberately -- the PRD makes that a precondition, and a DCA sleeve priced wrong is exactly the claim it was protecting against. THE BENCHMARK IS THE MEDIAN TICKER AT +70.62%, NOT THE POOLED SLEEVE AT +145.10%. The run's pre-declared refutation condition -- "a sleeve whose terminal value is dominated by one ticker, making 'beat DCA' a statement about NVDA rather than about equities" -- fired. NVDA returned +449.35% and is 44.8% of the terminal sleeve. Without it the remaining four returned +69.03%, within 1.6pp of the median, which is why the median is the honest summary. Quoting the pooled figure would set a bar one exceptional name built and then credit or blame a strategy for clearing it. THE COST ARMS BARELY DIFFER, AND THAT IS THE USEFUL PART. keel's 7.5x equities mispricing is worth 0.18 percentage points over five years here; even the fully counterfactual `crypto_regime` arm (Coinbase's 1.2%/leg on equity bars) costs 3.08pp. A DCA sleeve pays its spread 250 times, one way, on a position it never closes. This is the crypto finding reached from the other side and it is easy to get backwards: cost is levied on the SEARCH, not on the edge. Cheap execution does not make a strategy good; expensive execution makes a mediocre one impossible. `sim/portfolio_sim` is deliberately NOT used, and the record says why: it iterates ONE_HOUR bars (`_window_bars` is `history_days * 24`, mirroring the live agent's hourly account pass) and the equities profile is ONE_DAY only by configuration. Handing it daily bars labelled as hourly would produce numbers that look right and mean nothing. The accumulation loop is in the driver and calls the SHIPPED `Dca` rule, filling at the next bar's open plus one-way slippage -- keel's own market-order convention since #258, with the deciding bar always strictly before the filling bar. Tests (written first, red before green): tests/test_dca_benchmark_is_read_per_ticker.py -- 6 tests. They pin the PROSE, because that is where the damage would be done: the headline must name the median rather than the pooled figure, the concentration must be quantified BEFORE the first heading, the ex-NVDA row must survive, all three declared cost arms must still be reported, and the record must refuse to read as a recommendation. `test_one_ticker_really_does_dominate_the_sleeve` guards the premise -- if a re-run ever balances the sleeve, these fail loudly rather than enforce a caveat that no longer applies. Mutation-verified, 5 mutants, all killed. One initially survived: gutting the concentration sentence while the table's "44.8%" column kept the pin green. The pin now requires the figure in the opening, since a reader who takes the headline and stops is exactly who the caveat is for. Closes #371 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NzuKAe2RVrPt9acVAWjRyL
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Alpaca Phase C's second half, and the last of #371. It follows the cost-fidelity document in that order deliberately -- the PRD makes that a precondition, and a DCA sleeve priced wrong is exactly the claim it was protecting against.
THE BENCHMARK IS THE MEDIAN TICKER AT +70.62%, NOT THE POOLED SLEEVE AT +145.10%. The run's pre-declared refutation condition -- "a sleeve whose terminal value is dominated by one ticker, making 'beat DCA' a statement about NVDA rather than about equities" -- fired. NVDA returned +449.35% and is 44.8% of the terminal sleeve. Without it the remaining four returned +69.03%, within 1.6pp of the median, which is why the median is the honest summary. Quoting the pooled figure would set a bar one exceptional name built and then credit or blame a strategy for clearing it.
THE COST ARMS BARELY DIFFER, AND THAT IS THE USEFUL PART. keel's 7.5x equities mispricing is worth 0.18 percentage points over five years here; even the fully counterfactual
crypto_regimearm (Coinbase's 1.2%/leg on equity bars) costs 3.08pp. A DCA sleeve pays its spread 250 times, one way, on a position it never closes. This is the crypto finding reached from the other side and it is easy to get backwards: cost is levied on the SEARCH, not on the edge. Cheap execution does not make a strategy good; expensive execution makes a mediocre one impossible.sim/portfolio_simis deliberately NOT used, and the record says why: it iterates ONE_HOUR bars (_window_barsishistory_days * 24, mirroring the live agent's hourly account pass) and the equities profile is ONE_DAY only by configuration. Handing it daily bars labelled as hourly would produce numbers that look right and mean nothing. The accumulation loop is in the driver and calls the SHIPPEDDcarule, filling at the next bar's open plus one-way slippage -- keel's own market-order convention since #258, with the deciding bar always strictly before the filling bar.Tests (written first, red before green):
tests/test_dca_benchmark_is_read_per_ticker.py -- 6 tests. They pin the PROSE,
because that is where the damage would be done: the headline must name the
median rather than the pooled figure, the concentration must be quantified
BEFORE the first heading, the ex-NVDA row must survive, all three declared
cost arms must still be reported, and the record must refuse to read as a
recommendation.
test_one_ticker_really_does_dominate_the_sleeveguards thepremise -- if a re-run ever balances the sleeve, these fail loudly rather
than enforce a caveat that no longer applies.
Mutation-verified, 5 mutants, all killed. One initially survived: gutting the concentration sentence while the table's "44.8%" column kept the pin green. The pin now requires the figure in the opening, since a reader who takes the headline and stops is exactly who the caveat is for.
Closes #371
Claude-Session: https://claude.ai/code/session_01NzuKAe2RVrPt9acVAWjRyL
What & why
Tests-first evidence
Gates (all must pass)
uv run ruff checkcleanuv run mypycleanuv run pytest -qgreenScope check
leave checked only if true, and if so: cite the source and open the discussion
BEFORE review (CONTRIBUTING.md, "Governance: rulings vs. machinery").